package com.billdowney.controller.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.mail.MessagingException;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import com.billdowney.annotation.AuthRoleAllowed;
import com.billdowney.annotation.SystemLogInfo;
import com.billdowney.controller.BaseController;
import com.billdowney.dao.user.UserLoginInfoDao;
import com.billdowney.entity.base.EntityStatus;
import com.billdowney.entity.user.UserLoginInfo;
import com.billdowney.service.interfaces.system.notice.mail.MailService;
import com.billdowney.service.interfaces.system.quartz.QuartzManageService;
import com.billdowney.service.util.project.SystemAppConst;
import com.billdowney.util.CommonUtil;
import com.billdowney.util.DateUtil;
import com.billdowney.util.quartz.QuartzConst;
import com.billdowney.util.return_type.ReturnData;
import com.billdowney.util.spring.SpringUtil;
import com.billdowney.vo.mail.MailVO;
import com.billdowney.vo.system.quartz.JobDetailInfoVO;
import com.billdowney.vo.system.quartz.JobTriggerInfoVO;

@RestController
@ConditionalOnProperty(name = SystemAppConst.developModel, havingValue = "true")
public class TestController extends BaseController {

	@Autowired
	private UserLoginInfoDao userLoginInfoDao;
	@Autowired
	private SessionRegistry sessionRegistry;

	@SystemLogInfo("访问了test{a},{b}")
	@RequestMapping(value = "/test")
	public Object test(String a, String[] b, UserLoginInfo userLoginInfo) {
		ReturnData out = new ReturnData();
		Date date = new Date();
		Map<String, Object> data = new HashMap<>();
		// 放入时间戳，供前台使用
		data.put("longDate", date.getTime());
		data.put("method", Thread.currentThread().getStackTrace()[1].getMethodName());
		data.put("a", a);
		data.put("b", b);
		data.put("userLoginInfo", userLoginInfo);
		out.setData(data);
		return out;
	}

	// @PreAuthorize("hasAuthority('USER')")
	// @PreAuthorize("permitAll()")
	// @PermitAll
	@RequestMapping(value = "/test1")
	public Object test1(String str) {
		Map<String, Object> data = new HashMap<>();
		// data.put("user", userLoginInfoDao.findByUsername(str));
		Map<Object, Object> usersInfo = new HashMap<>();
		for (Object principal : sessionRegistry.getAllPrincipals()) {
			usersInfo.put(((UserLoginInfo) principal).getId(), sessionRegistry.getAllSessions(principal, false));
		}
		data.put("usersInfo", usersInfo);
		data.put("loginUser", getUserLoginInfo());
		data.put("loginUser1", SecurityContextHolder.getContext().getAuthentication());
		return new ReturnData(data);
	}

	@RequestMapping(value = "/test2")
	public Object test2(String username, String sessionId) {
		Map<String, Object> data = new HashMap<>();
		List<Object> users = sessionRegistry.getAllPrincipals(); // 获取session中所有的用户信息
		data.put("user", users);
		// SessionInformation sessionInformation =
		// sessionRegistry.getSessionInformation(sessionId);
//		if (sessionInformation != null) {
//			data.put("userSession", sessionInformation);
//			data.put("userInfo", sessionInformation.getPrincipal());
//			//sessionInformation.expireNow();
//		}
		for (Object principal : users) {
			if (principal instanceof UserLoginInfo) {
				final UserLoginInfo loggedUser = (UserLoginInfo) principal;
				// if (username.equals(loggedUser.getUsername())) {
				List<SessionInformation> sessionsInfo = sessionRegistry.getAllSessions(principal, false); // false代表不包含过期session
				if (null != sessionsInfo && sessionsInfo.size() > 0) {
					for (SessionInformation sessionInformation : sessionsInfo) {
						sessionInformation.expireNow();
						sessionRegistry.removeSessionInformation(sessionInformation.getSessionId());
					}
				}
				// }
			}
		}
		return new ReturnData(data);
	}

	@RequestMapping(value = "/test3")
	public Object test3(String username) {
		Map<String, Object> data = new HashMap<>();
		return new ReturnData(data);
	}

	@Autowired
	private RequestMappingHandlerMapping mapping;

	@RequestMapping(value = "/mappingTest")
	public Object mappingTest() {
		ReturnData out = new ReturnData();
		// 获取url与类和方法的对应信息
		Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		for (Entry<RequestMappingInfo, HandlerMethod> m : map.entrySet()) {
			Map<String, String> map1 = new HashMap<String, String>();
			RequestMappingInfo info = m.getKey();
			HandlerMethod method = m.getValue();
			method.hasMethodAnnotation(AuthRoleAllowed.class);
			AuthRoleAllowed authRole = method.getMethodAnnotation(AuthRoleAllowed.class);
			PatternsRequestCondition p = info.getPatternsCondition();
			for (String url : p.getPatterns()) {
				map1.put("url", url);
			}
			map1.put("className", method.getMethod().getDeclaringClass().getName()); // 类名
			map1.put("method", method.getMethod().getName()); // 方法名
			RequestMethodsRequestCondition methodsCondition = info.getMethodsCondition();
			String type = "";
			for (RequestMethod requestMethod : methodsCondition.getMethods()) {
				if (type.equals("")) {
					type = requestMethod.toString();
				} else {
					type += "," + requestMethod.toString();
				}
			}
			map1.put("type", type);
			list.add(map1);
		}
		out.setData(list);
		return out;
	}

	@Autowired
	private MailService mailService;

	/**
	 * 邮件测试
	 * 
	 * @return
	 * @author: 超级小富翁 - BillDowney
	 * @throws MessagingException
	 * @date: 2019年3月23日 下午10:14:48
	 */
	@RequestMapping(value = "/mailTest")
	public Object mailTest() throws MessagingException {
		MailVO mailVO = new MailVO();
		mailVO.setTo("773213931@qq.com");
		mailVO.setSubject("测试主题");
		mailVO.setContent("测试内容：<span style='color:red;'>" + DateUtil.getCurrentDate() + "</span>");
		Map<String, Object> templateParams = new HashMap<>();
		templateParams.put("name", "名称哦");
		mailVO.setTemplatePath("mail/test");
		mailVO.setTemplateParams(templateParams);
		mailVO.setFileIds("2c92bedc69b80f020169b80f7a370044");
		mailService.sendTemplateMail(mailVO);
		return new ReturnData();
	}

	@RequestMapping(value = "/test4")
	public Object test4(EntityStatus status) {
		return new ReturnData(status);
	}

	public static void main(String[] args) {
		System.out.println(TestController.class.getName());
		System.out.println(TestController.class.getSimpleName());
		System.out.println(TestController.class.getTypeName());
		System.out.println(TestController.class.getCanonicalName());
	}

	@Autowired
	private Scheduler scheduler;
	@Autowired
	private QuartzManageService quartzManageService;

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/scheduler")
	public Object test4() throws Exception {
		Class<Job> clazz = (Class<Job>) Class.forName(TestJob.class.getName());
		// 创建JobDetail（数据库中job_name存的任务全路径，这里就可以动态的把任务注入到JobDetail中）
		JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(clazz.getName(), QuartzConst.JOB_GROUP_NAME)
				.withDescription("测试任务每五秒执行一次").storeDurably().build();
		jobDetail.getJobDataMap().put("jobDetail_1", "jobDetail测试值1");
		jobDetail.getJobDataMap().put("jobDetail_2", "jobDetail测试值2");
		jobDetail.getJobDataMap().put("jobDetail_3", "jobDetail测试值3");
		// 表达式调度构建器
		CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
		// 把trigger和jobDetail注入到调度器
		TriggerBuilder<Trigger> trigger = TriggerBuilder.newTrigger().withIdentity(clazz.getName() + "_1",
				QuartzConst.TRIGGER_GROUP_NAME);
		trigger.withSchedule(scheduleBuilder);
		trigger.usingJobData("trigger_1", "trigger测试值1");
		trigger.usingJobData("trigger_2", "trigger测试值2");
		trigger.forJob(jobDetail);
		if (scheduler.checkExists(jobDetail.getKey())) {
			scheduler.deleteJob(new JobKey(clazz.getName(), QuartzConst.JOB_GROUP_NAME));
		} else {
			scheduler.addJob(jobDetail, true);
			scheduler.scheduleJob(trigger.build());
		}
		return new ReturnData(scheduler);
	}

	@RequestMapping(value = "/getJobList")
	public Object test5(JobTriggerInfoVO jobTriggerInfoVO, JobDetailInfoVO jobDetailInfoVO) throws Exception {
		// return new ReturnData(SpringUtil.getBeansOfType(Job.class));
		JobDetail jobDetail = scheduler.getJobDetail(new JobKey(TestJob.class.getName(), QuartzConst.JOB_GROUP_NAME));
		// jobDetail.getDescription();
		return new ReturnData(
				quartzManageService.getJobTriggerList(new JobKey(TestJob.class.getName(), QuartzConst.JOB_GROUP_NAME)));
	}
}
